package controllers;

import java.util.*;
import models.*;
import play.mvc.Controller;
import play.mvc.With;

@With(Secure.class)
public class QuickSearch extends Controller {

    /**retrieves the tags with name contains the search paramater 
     * 
     * @param search
     * the word to search with
     * @return list of tags
     */
    public static List<Tag> getTags(String search) {
        String likeSearch = "%" + search + "%";
        return Tag.find("name like?", likeSearch).fetch();
    }

    /**
     * decides which query to use to retrieve the topics from the data base according to the sort parameter
     * @param search
     * the word to search with
     * @param page
     * the number of the oage desplayed to fetch with
     * @param developer
     * the user in the session
     * @param sort
     * the sorting chosen
     * @return QuickSearchResultsTopic 
     */
    public static QuickSearchResultsTopic searchTitleorDescriptionTopic(String search, Integer page, IdeaDeveloper developer, int sort) {
        QuickSearchResultsTopic resultsTopic = null;
        if (sort == 1) {//numberOfViewsDsc
            resultsTopic = searchTitleorDescriptionTopic(search, page, developer,
                    " title like ? or description like ? order by numberOfViews DESC");
        }
        if (sort == 2) {//relevanceDsc
            resultsTopic = searchTitleorDescriptionTopic(search, page, developer,
                    " title like ? or description like ?");
            List<Topic> items = (List<Topic>) sortTopicByRelevance(
                    (ArrayList<Topic>) resultsTopic.items, search);
            resultsTopic = new QuickSearchResultsTopic(items, resultsTopic.count);
        }
        if (sort == 3) {//dateDsc
            resultsTopic = searchTitleorDescriptionTopic(search, page, developer,
                    "title like ? or description like ? order by dateOfDraftingPosting DESC");
        }
        if (sort == 4) {//rateDsc
            resultsTopic = searchTitleorDescriptionTopic(search, page, developer,
                    "select T from Topic T join T.rates as R "
                    + "where T.title like ? or T.description like ? order by R.rating DESC");
        }
        if (sort == 5) {//numberOfViewsAsc
            resultsTopic = searchTitleorDescriptionTopic(search, page, developer,
                    " title like ? or description like ? order by numberOfViews ASC");
        }

        if (sort == 6) {//dateAsc
            resultsTopic = searchTitleorDescriptionTopic(search, page, developer,
                    "title like ? or description like ? order by dateOfDraftingPosting ASC");
        }
        if (sort == 7) {//rateAsc
            resultsTopic = searchTitleorDescriptionTopic(search, page, developer,
                    "select T from Topic T join T.rates as R "
                    + "where T.title like ? or T.description like ? order by R.rating ASC");
        }
        return resultsTopic;

    }

    /**
     * decides which query to use to retrieve the ideas fromthe data base according to the sort parameter
     * @param search
     * the word to search with
     * @param page
     * the displayed page to fetch with
     * @param developer
     * the user in the session
     * @param sort
     * the sorting chosen
     * @return QuickSearchResultsIdea
     */
    public static QuickSearchResultsIdea searchDescriptionIdea(String search, Integer page, IdeaDeveloper developer, int sort) {
        QuickSearchResultsIdea resultsIdea = null;
        if (sort == 1) {//numberOfViewsDsc
            resultsIdea = searchDescriptionIdea(search, page, developer,
                    "description like ? order by numberOfViews DESC");
        }
        if (sort == 2) {//relevance
            resultsIdea = searchDescriptionIdea(search, page, developer,
                    "description like ?");
            List<Idea> items = (List<Idea>) sortIdeaByRelevance(
                    (ArrayList<Idea>) resultsIdea.items, search);
            resultsIdea = new QuickSearchResultsIdea(items, resultsIdea.count);

        }
        if (sort == 3) {//dateDsc
            resultsIdea = searchDescriptionIdea(search, page, developer,
                    "description like ? order by dateOfDraftingPosting DESC");
        }
        if (sort == 4) {//rateDsc
            resultsIdea = searchDescriptionIdea(search, page, developer,
                    "select T from Idea T join T.rates as R "
                    + "where T.description like ? order by R.rating DESC");
        }
        if (sort == 5) {//noOfVotesDsc
            resultsIdea = searchDescriptionIdea(search, page, developer,
                    "description like ? order by noOfVotes DESC");
        }
        if (sort == 6) {//numberOfViewsAsc
            resultsIdea = searchDescriptionIdea(search, page, developer,
                    "description like ? order by numberOfViews ASC");
        }

        if (sort == 7) {//dateAsc
            resultsIdea = searchDescriptionIdea(search, page, developer,
                    "description like ? order by dateOfDraftingPosting ASC");
        }
        if (sort == 8) {//rateAsc
            resultsIdea = searchDescriptionIdea(search, page, developer,
                    "select T from Idea T join T.rates as R "
                    + "where T.description like ? order by R.rating ASC");
        }
        if (sort == 9) {//noOfVotesAsc
            resultsIdea = searchDescriptionIdea(search, page, developer,
                    "description like ? order by noOfVotes ASC");
        }
        return resultsIdea;

    }

    /**
     * decides which query to use to retrive the tags from the data base according to the sort parameter 
     * @param search
     * the word to search with
     * @param page
     * the page displayed used to fetch from the data base
     * @param developer
     * the user in the session
     * @param sort
     * the sorting chosen
     * @return QuickSearchResultsTag
     */
    public static QuickSearchResultsTag quickSearchTag(String search, Integer page, IdeaDeveloper developer, int sort) {
        QuickSearchResultsTag resultsTag = null;
        if (sort == 1) {//dateDsc
            resultsTag = quickSearchTag(search, page, developer,
                    "name like ? order by dateOfCreation DESC");
        }
        if (sort == 2) {//relevance
        }
        if (sort == 3) {//relatedItemsDsc
            resultsTag = quickSearchTag(search, page, developer,
                    "name like ? order by relatedItems DESC");
        }
        if (sort == 4) {//dateAsc
            resultsTag = quickSearchTag(search, page, developer,
                    "name like ? order by dateOfCreation ASC");
        }

        if (sort == 5) {//relatedItemsAsc
            resultsTag = quickSearchTag(search, page, developer,
                    "name like ? order by relatedItems ASC");
        }
        return resultsTag;

    }

    /**
     * retrives the tags with name contains the search parameter from the data base 
     * @param search
     * the word to search with
     * @param page
     * the page displayed used to fetch from the data base
     * @param developer
     * the user in the session
     * @param query
     * the query used to fetch the results from the data base
     * @return QuickSearchResultsTag
     */
    public static QuickSearchResultsTag quickSearchTag(String search,
            Integer page, IdeaDeveloper developer, String query) {
        String likeSearch = "%" + search + "%";
        int count = Tag.find(query, likeSearch).fetch().size();
        List<Tag> itemsBeforePriv = Tag.find(query, likeSearch).fetch(page, 10);

        return new QuickSearchResultsTag(itemsBeforePriv, count);
    }

    /**
     * decides which query to use to retrieve the organization from the data base according to the sort parameter
     * @param search
     * the word to search with
     * @param page
     * the page displayed used to fetch from the data base
     * @param developer
     * the user in the session
     * @param sort
     * the sorting chosen
     * @return QuickSearchResultsOrganization
     */
    public static QuickSearchResultsOrganization searchNameOrganization(String search, Integer page, IdeaDeveloper developer, int sort) {
        QuickSearchResultsOrganization resultsOrganization = null;
        if (sort == 1) {//viewsDsc
            resultsOrganization = searchNameOrganization(search, page, developer,
                    " name like ?  order by views DESC");
        }
        if (sort == 2) {//relevance
        }
        if (sort == 3) {
            resultsOrganization = searchNameOrganization(search, page, developer,
                    " name like ?  order by date DESC");
        }
        if (sort == 4) {//rateDsc
            resultsOrganization = searchNameOrganization(search, page, developer,
                    "select T from Organization T join T.rates as R "
                    + "where T.name like ? order by R.rating DESC");
        }
        if (sort == 5) {//membersDsc
            resultsOrganization = searchNameOrganization(search, page, developer,
                    "name like ?  order by noOfMembers DESC");
        }
        if (sort == 6) {//viewsAsc
            resultsOrganization = searchNameOrganization(search, page, developer,
                    " name like ?  order by views ASC");
        }

        if (sort == 7) {//dateAsc
            resultsOrganization = searchNameOrganization(search, page, developer,
                    " name like ?  order by date ASC");
        }
        if (sort == 8) {//rateAsc
            resultsOrganization = searchNameOrganization(search, page, developer,
                    "select T from Organization T join T.rates as R "
                    + "where T.name like ? order by R.rating ASC");
        }
        if (sort == 9) {//membersASc
            resultsOrganization = searchNameOrganization(search, page, developer,
                    "name like ?  order by noOfMembers ASC");
        }
        return resultsOrganization;

    }

    /**
     * decides which query to use to retrive the entities from the data base according to the sort parameter
     * @param search
     * the word to search with
     * @param page
     * the page displayed used to fetch from the database
     * @param developer
     * the user in the session
     * @param sort
     * the sorting chosen
     * @return QuickSearchResultsEntity
     */
    public static QuickSearchResultsEntity searchNameEntity(String search, Integer page, IdeaDeveloper developer, int sort) {
        QuickSearchResultsEntity resultsEntity = null;
        if (sort == 1) {//viewsDsc
            resultsEntity = searchNameEntity(search, page, developer,
                    " name like ?  order by views DESC");
        }
        if (sort == 2) {//relevance
        }
        if (sort == 3) {
            resultsEntity = searchNameEntity(search, page, developer,
                    " name like ?  order by date DESC");
        }
        if (sort == 4) {//rateDsc
            resultsEntity = searchNameEntity(search, page, developer,
                    "select T from Entities T join T.rates as R "
                    + "where T.name like ? order by R.rating DESC");
        }
        if (sort == 5) {//viewsAsc
            resultsEntity = searchNameEntity(search, page, developer,
                    " name like ?  order by views ASC");
        }

        if (sort == 6) {//dateAsc
            resultsEntity = searchNameEntity(search, page, developer,
                    " name like ?  order by date ASC");
        }
        if (sort == 7) {//rateAsc
            resultsEntity = searchNameEntity(search, page, developer,
                    "select T from Entities T join T.rates as R "
                    + "where T.name like ? order by R.rating ASC");
        }
        return resultsEntity;

    }

    /**
     * decides which query to use to retrieve the action plan from data base according to the sort parameter
     * @param search
     * the word to search with
     * @param page
     * the page displayed used to fetch from the database
     * @param developer
     * the user in the session
     * @param sort
     * the sorting chosen
     * @return QuickSearchResultsActionplan
     */
    public static QuickSearchResultsActionplan searchNameActionplan(String search, Integer page, IdeaDeveloper developer, int sort) {
        QuickSearchResultsActionplan resultsActionplan = null;
        if (sort == 1) {//viewsDsc
            resultsActionplan = searchNameActionplan(search, page, developer,
                    " name like ? or description like ? order by views DESC");
        }
        if (sort == 2) {//relevance
        }
        if (sort == 3) {//dateDsc
            resultsActionplan = searchNameActionplan(search, page, developer,
                    " name like ? or description like ? order by startDate DESC");
        }
        if (sort == 4) {//rateDsc
            resultsActionplan = searchNameActionplan(search, page, developer,
                    "select T from ActionPlan T join T.rates as R "
                    + "where T.name like ? or T.description like ? order by R.rating DESC");
        }
        if (sort == 5) {//viewsAsc
            resultsActionplan = searchNameActionplan(search, page, developer,
                    "name like ? or description like ? order by views ASC");
        }
        if (sort == 6) {//dateAsc
            resultsActionplan = searchNameActionplan(search, page, developer,
                    "name like ? or description like ? order by startDate ASC");
        }
        if (sort == 7) {//rateAsc
            resultsActionplan = searchNameActionplan(search, page, developer,
                    "select T from ActionPlan T join T.rates as R "
                    + "where T.name like ? or T.description like ? order by R.rating ASC");
        }
        return resultsActionplan;

    }

    /**
     * retrieves the topics which title or description contains the search parameter from the database 
     * and check the privileges of the developer parameter 
     * @param search
     * the word to search with
     * @param page
     * the page displayed used to fetch from the database 
     * @param developer
     * the user in the session
     * @param query
     * the query used to fetch the results from the database
     * @return QuickSearchResultsActionplan
     */
    public static QuickSearchResultsTopic searchTitleorDescriptionTopic(String search,
            Integer page, IdeaDeveloper developer, String query) {
        String likeSearch = "%" + search + "%";
        List<Topic> itemsForCount = Topic.find(query, likeSearch, likeSearch).fetch();
        ArrayList<Topic> itemsForCountAfterPriv = new ArrayList<Topic>();
        for (int j = 0; j < itemsForCount.size(); j++) {
            if (developer.canViewTopic(developer, itemsForCount.get(j))) {
                itemsForCountAfterPriv.add(itemsForCount.get(j));
            }
        }
        long count = itemsForCountAfterPriv.size();
        List<Topic> itemsBeforePriv = Topic.find(query, likeSearch, likeSearch).fetch(page, 10);
        ArrayList<Topic> itemsAfterPriv = new ArrayList<Topic>();
        for (int i = 0; i < itemsBeforePriv.size(); i++) {
            if (developer.canViewTopic(developer, itemsBeforePriv.get(i))) {
                itemsAfterPriv.add(itemsBeforePriv.get(i));
            }
        }//List<Topic> items=Sort.sortTopicByRelevance(items2, search);*/
        return new QuickSearchResultsTopic(itemsAfterPriv, count);
    }

    /**
     *retrieves the ideas with description contains the search parameter from the database 
     * and check the privileges of the developer parameter
     *@param search
     * the word to search with
     *@param page
     * the page displayed used to fetch from the database
     *@param developer
     * the user in the session
     *@return QuickSearchResultsIdea
     */
    public static QuickSearchResultsIdea searchDescriptionIdea(String search, Integer page, IdeaDeveloper developer, String query) {
        String likeSearch = "%" + search + "%";
        List<Idea> itemsForCount = Idea.find(query, likeSearch).fetch();
        ArrayList<Idea> itemsForCountAfterPriv = new ArrayList<Idea>();
        for (int j = 0; j < itemsForCount.size(); j++) {
            if (developer.canViewIdea(developer, itemsForCount.get(j))) {
                itemsForCountAfterPriv.add(itemsForCount.get(j));
            }
        }
        long count = itemsForCountAfterPriv.size();
        List<Idea> itemsBeforePriv = Idea.find(query, likeSearch).fetch(page, 10);
        ArrayList<Idea> itemsAfterPriv = new ArrayList<Idea>();
        for (int i = 0; i < itemsBeforePriv.size(); i++) {
            if (developer.canViewIdea(developer, itemsBeforePriv.get(i))) {
                itemsAfterPriv.add(itemsBeforePriv.get(i));
            }
        }//List items=Sort.sortIdeaByRelevance(items2, search);*/
        return new QuickSearchResultsIdea(itemsAfterPriv, count);
    }

    /**
     *retrives the idea developers with username or fullName contains the search parameter 
     * and check the privileges of the developer parameter
     *@param search 
     * the word to search with
     *@param page
     * the displayed page used to fetch from the data base
     *@param developer
     * the uset in the session
     *@return QuickSearchResultsIdeaDeveloper
     */
    public static QuickSearchResultsIdeaDeveloper searchMemberSystem(String search,
            Integer page, IdeaDeveloper developer) {
        String likeSearch = "%" + search + "%";
        List<IdeaDeveloper> itemsForCount = IdeaDeveloper.find("username like ? or fullName like ?", likeSearch, likeSearch).fetch();
        ArrayList<IdeaDeveloper> itemsForCountAfterPriv = new ArrayList<IdeaDeveloper>();
        for (int j = 0; j < itemsForCount.size(); j++) {
            if (developer.canViewProfile(developer, itemsForCount.get(j))) {
                itemsForCountAfterPriv.add(itemsForCount.get(j));
            }
        }
        long count = itemsForCountAfterPriv.size();

        List<IdeaDeveloper> itemsBeforePriv = IdeaDeveloper.find("username like ? or fullName like ?", likeSearch, likeSearch).fetch(page, 10);
        ArrayList<IdeaDeveloper> itemsAfterPriv = new ArrayList<IdeaDeveloper>();
        for (int i = 0; i < itemsBeforePriv.size(); i++) {
            if (developer.canViewProfile(developer, itemsBeforePriv.get(i))) {
                itemsAfterPriv.add(itemsBeforePriv.get(i));
            }
        }

        return new QuickSearchResultsIdeaDeveloper(itemsAfterPriv, count);


    }

    /**
     * retrives the idea developers with username or fullName contains the search parameter
     * @param search
     * the word to search with
     * @return list of idea developer
     */
    public static List<IdeaDeveloper> searchMemberSystemNoPaging(String search) {
        String likeSearch = "%" + search + "%";
        List<IdeaDeveloper> items = IdeaDeveloper.find("username like ? or fullName like ?",
                likeSearch, likeSearch).fetch();
        return items;
    }

    /**
     *retrives the idea developers with fullName contains the search parameter and members in a certain organization
     *@param search
     * the word to search with
     *@param page
     * the displayed page used to fetch from the database
     **@param organization
     * the oraganization specified to search within
     *@return QuickSearchResultsIdeaDeveloper
     */
    public static QuickSearchResultsIdeaDeveloper searchMemberOrganization(String search,
            Integer page, String orgName) {
        String likeSearch = "%" + search + "%";
        long count = IdeaDeveloper.find(
                "select  d from IdeaDeveloper d join d.organizationsJoined "
                + "as o where o.name = ? and (d.fullName like ? or d.username like ?)",
                orgName, likeSearch).fetch().size();
        List<IdeaDeveloper> items = IdeaDeveloper.find(
                "select  d from IdeaDeveloper d join d.organizationsJoined "
                + "as o where o.name = ? and (d.fullName like ? or d.username like ?)",
                orgName, likeSearch).fetch(page, 20);

        return new QuickSearchResultsIdeaDeveloper(items, count);
    }

    /**
     *retrives the organizations with name contains the search parameter form the database 
     * and check the privileges of the developer parameter 
     *@param search
     * the word to search with
     *@param page
     * the displayed page used to fetch from the data base
     *@param developer
     * the user in the session
     *@param query
     * the query used to fetch from the database
     *@return QuickSearchResultsOrganization
     */
    public static QuickSearchResultsOrganization searchNameOrganization(String search,
            Integer page, IdeaDeveloper developer, String query) {
        String likeSearch = "%" + search + "%";
        List<Organization> itemsForCount = Organization.find(query, likeSearch).fetch();
        ArrayList<Organization> itemsForCountAfterPriv = new ArrayList<Organization>();
        for (int j = 0; j < itemsForCount.size(); j++) {
            if (developer.canViewOrganization(developer, itemsForCount.get(j))) {
                itemsForCountAfterPriv.add(itemsForCount.get(j));
            }
        }
        long count = itemsForCountAfterPriv.size();
        List<Organization> itemsBeforePriv = Organization.find(query, likeSearch).fetch(page, 10);
        ArrayList<Organization> itemsAfterPriv = new ArrayList<Organization>();
        for (int i = 0; i < itemsBeforePriv.size(); i++) {
            if (developer.canViewOrganization(developer, itemsBeforePriv.get(i))) {
                itemsAfterPriv.add(itemsBeforePriv.get(i));
            }
        }//List<Organization> items=Sort.sortTopicByRelevance(items2, search);*/
        return new QuickSearchResultsOrganization(itemsAfterPriv, count);
    }

    /**
     *retrives the action plans with name or description contains the search parameter form the database 
     * and check the privileges of the developer parameter 
     *@param search
     * the word to search with
     *@param page
     * the displayed page used to fetch from the database
     *@param developer
     * the user in the session
     *@param query
     * the query used to fetch the results from the database
     *@return QuickSearchResultsActionplan
     */
    public static QuickSearchResultsActionplan searchNameActionplan(String search,
            Integer page, IdeaDeveloper developer, String query) {
        String likeSearch = "%" + search + "%";
        List<ActionPlan> itemsForCount = ActionPlan.find(query, likeSearch, likeSearch).fetch();
        ArrayList<ActionPlan> itemsForCountAfterPriv = new ArrayList<ActionPlan>();
        for (int j = 0; j < itemsForCount.size(); j++) {
            if (developer.canViewActionPlan(developer, itemsForCount.get(j))) {
                itemsForCountAfterPriv.add(itemsForCount.get(j));
            }
        }
        long count = itemsForCountAfterPriv.size();
        List<ActionPlan> itemsBeforePriv = ActionPlan.find(query, likeSearch, likeSearch).fetch(page, 10);
        ArrayList<ActionPlan> itemsAfterPriv = new ArrayList<ActionPlan>();
        for (int i = 0; i < itemsBeforePriv.size(); i++) {
            if (developer.canViewActionPlan(developer, itemsBeforePriv.get(i))) {
                itemsAfterPriv.add(itemsBeforePriv.get(i));
            }
        }//List<ActionPlan> items=Sort.sortTopicByRelevance(items2, search);
        return new QuickSearchResultsActionplan(itemsAfterPriv, count);
    }

    /**
     *retrives the entities with name contains the search parameter form the database 
     * and check the privileges of the developer parameter
     *@param search
     * the word to search with
     *@param page
     * the displayed page used to fetch from the database
     *@param developer
     * the user in the session
     *@param query
     * the query used to fetch from the databse
     *@return QuickSearchResultsEntity
     */
    public static QuickSearchResultsEntity searchNameEntity(String search,
            Integer page, IdeaDeveloper developer, String query) {
        String likeSearch = "%" + search + "%";
        List<Entities> itemsForCount = Entities.find(query, likeSearch).fetch();
        ArrayList<Entities> itemsForCountAfterPriv = new ArrayList<Entities>();
        for (int j = 0; j < itemsForCount.size(); j++) {
            if (developer.canViewEntity(developer, itemsForCount.get(j))) {
                itemsForCountAfterPriv.add(itemsForCount.get(j));
            }
        }
        long count = itemsForCountAfterPriv.size();
        List<Entities> itemsBeforePriv = Entities.find(query, likeSearch).fetch(page, 10);
        ArrayList<Entities> itemsAfterPriv = new ArrayList<Entities>();
        for (int i = 0; i < itemsBeforePriv.size(); i++) {
            if (developer.canViewEntity(developer, itemsBeforePriv.get(i))) {
                itemsAfterPriv.add(itemsBeforePriv.get(i));
            }
        }//List<Entity> items=Sort.sortTopicByRelevance(items2, search);*/
        return new QuickSearchResultsEntity(itemsAfterPriv, count);
    }

    /**
     * matchValue is a method that take two strings and checks how many words match inside these strings giving it points
     * according to the method matchValueHelp
     * @param compare1
     * the first string that is compared
     * @param compare2
     * the second string that is compared
     * @return
     * double that represents how they match
     */
    public static double matchValue(String compare1, String compare2) {
        String[] compareWhole1 = compare1.split(" ");
        String[] compareWhole2 = compare2.split(" ");
        double matchValue = 0.0;

        //This loop moves through the first array to check each string in it with the strings in the other array
        for (int i = 0; i < compareWhole1.length; i++) {
            for (int j = 0; j < compareWhole2.length; j++) {
                matchValue += matchValueHelp(compareWhole1[i], compareWhole2[j]);
            }
        }

        return matchValue;
    }

    /**
     * matchValueHelp method takes two strings and compares them by each character and returns back a double which
     * represents the ratio of matching
     * @param compare1
     * the first string to compare with
     * @param compare2
     * the second string to compare with
     * @return
     * double that represents how they match
     */
    public static double matchValueHelp(String compare1, String compare2) {
        double matchValue = 0.0;
        double matchedCharacters = 0.0;
        int smallerString = 0;
        int largerString = 0;

        smallerString = (compare1.length() < compare2.length()) ? compare1.length() : compare2.length();
        largerString = (compare1.length() < compare2.length()) ? compare2.length() : compare1.length();

        for (int i = 0; i < smallerString; i++) {
            if (compare1.charAt(i) == compare2.charAt(i)) {
                matchedCharacters++;
            } else {
                compare2 = compare2.substring(1);
                i = 0;
            }
        }

        matchValue = matchedCharacters / largerString;
        return matchValue;
    }

    /**
     *
     * @param input
     * A linkedlist of organizations that should be sorted
     * @param searchWord
     * The string the user searhcing for
     * @return
     * A linkedlist of organizations but sorted according to relevance by using the matchValue() method
     */
    public static List<Idea> sortIdeaByRelevance(ArrayList<Idea> input, String searchWord) {
        ArrayList<Idea> out = new ArrayList<Idea>();
        double[] points = new double[input.size()];
        Idea idea;
        for (int i = 0; i < input.size(); i++) {
            idea = input.get(i);
            points[i] += matchValue(searchWord, idea.description);
        }

        for (int i = 0; i < points.length - 1; i++) {
            int minIndex = i;
            double min = points[minIndex];
            for (int j = i + 1; j < points.length; j++) {
                if (points[j] < min) {
                    minIndex = j;
                    min = points[minIndex];
                }
            }
            double T = points[minIndex];
            Idea x = out.remove(minIndex);
            points[minIndex] = points[i];
            out.add(minIndex, out.get(i));
            points[i] = T;
            out.remove(i);
            out.add(i, x);
        }

        return out;
    }

    public static List<Topic> sortTopicByRelevance(ArrayList<Topic> input, String searchWord) {
        ArrayList<Topic> out = new ArrayList<Topic>();
        double[] points = new double[input.size()];
        Topic topic;
        for (int i = 0; i < input.size(); i++) {
            topic = input.get(i);
            points[i] += matchValue(searchWord, topic.description);
        }

        for (int i = 0; i < points.length - 1; i++) {
            int minIndex = i;
            double min = points[minIndex];
            for (int j = i + 1; j < points.length; j++) {
                if (points[j] < min) {
                    minIndex = j;
                    min = points[minIndex];
                }
            }
            double T = points[minIndex];
            Topic x = out.remove(minIndex);
            points[minIndex] = points[i];
            out.add(minIndex, out.get(i));
            points[i] = T;
            out.remove(i);
            out.add(i, x);
        }
        return out;
    }
}
